package com.easylinkin.linkappapi.classroom.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easylinkin.linkappapi.classroom.entity.GfdRoleRefArea;
import com.easylinkin.linkappapi.classroom.mapper.GfdRoleRefAreaMapper;
import com.easylinkin.linkappapi.classroom.service.GfdRoleRefAreaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.security.constant.LinkappUserConstant;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappRole;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import com.easylinkin.linkappapi.space.entity.LinkappArea;
import com.easylinkin.linkappapi.space.entity.LinkappSpace;
import com.easylinkin.linkappapi.space.mapper.LinkappAreaMapper;
import com.easylinkin.linkappapi.space.mapper.LinkappSpaceMapper;
import com.easylinkin.linkappapi.space.service.LinkappAreaService;
import com.easylinkin.linkappapi.space.vo.SpaceTreeVo;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 国防大角色关联区域 服务实现类
 * </p>
 *
 * @author TongJie
 * @since 2021-09-24
 */
@Service
public class GfdRoleRefAreaServiceImpl extends ServiceImpl<GfdRoleRefAreaMapper, GfdRoleRefArea> implements GfdRoleRefAreaService {

    @Resource
    LinkappUserService linkappUserService;

    @Resource
    LinkappAreaMapper linkappAreaMapper;

    @Resource
    LinkappAreaService linkappAreaService;

    @Resource
    LinkappSpaceMapper linkappSpaceMapper;

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Override
    public List<LinkappArea> getAreasByUser(LinkappUser linkappUser) {
        LinkappUser user = linkappUserService.get(linkappUser.getId());

        if (user == null || CollectionUtils.isEmpty(user.getRoles())) {
            return Collections.emptyList();
        }
        if ("1".equals(user.getType())){
            throw new BusinessException("请检查参数，管理员用户不用查询区域权限！");
        }
        List<Long> roleIds = user.getRoles().stream().map(LinkappRole::getId).collect(Collectors.toList());
        return baseMapper.getAreasByRoles(roleIds);
    }

    @Override
    public List<SpaceTreeVo> selectLinkappAreaTreeList(LinkappArea linkappArea) {
        LinkappUser user = linkappUserContextProducer.getCurrent();
        user = linkappUserService.get(user.getId());
        List<SpaceTreeVo> spaceTreeVoResultList = new ArrayList<>();
        List<SpaceTreeVo> allSpaceTreeVOList = linkappAreaMapper.selectLinkappAreaTreeList(linkappArea);
        //空间权限过滤
        if (LinkappUserConstant.ADMIN_TYPE.equals(user.getType())) {
            return allSpaceTreeVOList;
        } else {
            List<LinkappSpace> spaceList = linkappSpaceMapper.selectLinkappSpaceByUser(user.getId().toString());
            List<String> spaces = new ArrayList<String>();
            if (spaceList.isEmpty()) {
                spaces.add("-1");
                linkappArea.setSpaceIds(spaces);
            } else {
                for (LinkappSpace space : spaceList) {
                    spaces.add(space.getId());
                }
                linkappArea.setSpaceIds(spaces);
            }
            List<SpaceTreeVo> spaceTreeVoList = linkappAreaMapper.selectLinkappAreaTreeList(linkappArea);
            if(ObjectUtils.isEmpty(spaceTreeVoList)){
                return Collections.emptyList();
            }
            if (user == null || CollectionUtils.isEmpty(user.getRoles())) {
                return Collections.emptyList();
            }

            //获取角色绑定的国科大教室空间区域，进行数据过滤
            List<Long> roleIds = user.getRoles().stream().map(LinkappRole::getId).collect(Collectors.toList());
            List<LinkappArea> areasByRoles = baseMapper.getAreasByRoles(roleIds);
            if(ObjectUtils.isEmpty(areasByRoles)){
                return Collections.emptyList();
            }else {
                List<String> roleRefAreaIds = areasByRoles.stream().map(LinkappArea::getId).collect(Collectors.toList());
                for (SpaceTreeVo stv:
                        spaceTreeVoList) {
                    if(roleRefAreaIds.contains(stv.getId())){
                        spaceTreeVoResultList.add(stv);
                    }
                }
            }
            spaceTreeVoResultList = fillParentTree(allSpaceTreeVOList, spaceTreeVoResultList);
        }
        linkappAreaService.setMostChildFlag(spaceTreeVoResultList);
        return spaceTreeVoResultList;
    }

    private List<SpaceTreeVo> fillParentTree(List<SpaceTreeVo> allSpaceTreeVOList, List<SpaceTreeVo> spaceTreeVoResultList){
        Map<String, List<SpaceTreeVo>> allCollectMap = allSpaceTreeVOList.stream().collect(Collectors.groupingBy(SpaceTreeVo::getId));
        Map<String, List<SpaceTreeVo>> childCollectMap = spaceTreeVoResultList.stream().collect(Collectors.groupingBy(SpaceTreeVo::getId));
        List<SpaceTreeVo> temList = new ArrayList<>();
        temList.addAll(spaceTreeVoResultList);
        for (SpaceTreeVo stv:
                temList) {
            getParentArea(stv, allCollectMap, childCollectMap);
        }
//        List<SpaceTreeVo> result = new ArrayList(childCollectMap.values());
        List<SpaceTreeVo> result = new ArrayList();
        for (Map.Entry<String, List<SpaceTreeVo>> entry : childCollectMap.entrySet()){
            result.add(entry.getValue().get(0));
        }
        return result;
    }

    private void getParentArea(SpaceTreeVo stv, Map<String, List<SpaceTreeVo>> allCollectMap, Map<String, List<SpaceTreeVo>> childCollectMap){
        if(StrUtil.isNotEmpty(stv.getParentId())){
            List<SpaceTreeVo> spaceTreeVoList = allCollectMap.get(stv.getParentId());
            if(ObjectUtils.isNotEmpty(spaceTreeVoList)){
                if(!childCollectMap.containsKey(spaceTreeVoList.get(0).getId())){
                    childCollectMap.put(spaceTreeVoList.get(0).getId(), spaceTreeVoList);
                    getParentArea(spaceTreeVoList.get(0), allCollectMap, childCollectMap);
                }
            }
        }
    }

    @Override
    public String saveRoleRefArea(GfdRoleRefArea roleRefArea) {
        Assert.notNull(roleRefArea.getRoleId(), "角色ID不能为空");
        Assert.notNull(roleRefArea.getAreaId(), "区域ID不能为空");
        QueryWrapper qw = new QueryWrapper();
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        qw.eq("tenant_id", tenantId);
        qw.eq("role_id", roleRefArea.getRoleId());
        Integer count = baseMapper.selectCount(qw);
        if(count != null && count > 0){
            return "该角色已绑定区域";
        }
        roleRefArea.setTenantId(tenantId);
        roleRefArea.setCreateTime(new Date());
        roleRefArea.setModifyTime(new Date());
        save(roleRefArea);
        return null;
    }

    @Override
    public String updateRoleRefArea(GfdRoleRefArea roleRefArea) {
        Assert.notNull(roleRefArea.getId(), "角色ID不能为空");
        Assert.notNull(roleRefArea.getRoleId(), "角色ID不能为空");
        Assert.notNull(roleRefArea.getAreaId(), "区域ID不能为空");
        QueryWrapper qw = new QueryWrapper();
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        qw.eq("tenant_id", tenantId);
        qw.eq("role_id", roleRefArea.getRoleId());
        qw.notIn("id", roleRefArea.getId());
        Integer count = baseMapper.selectCount(qw);
        if(count != null && count > 0){
            return "该角色已绑定区域";
        }
        roleRefArea.setModifyTime(new Date());
        updateById(roleRefArea);
        return null;
    }

    @Override
    public void deleteRoleRefArea(String deleteIds) {
        Assert.notNull(deleteIds, "主键ID不能为空");
        String[] split = deleteIds.split(",");
        int[] array = Arrays.asList(split).stream().mapToInt(Integer::parseInt).toArray();
        QueryWrapper qw = new QueryWrapper();
        if(array.length == 1){
            baseMapper.deleteById(array[0]);
        }else {
            List<Integer> idList = Arrays.stream(array).boxed().collect(Collectors.toList());
            baseMapper.deleteBatchIds(idList);
        }
    }

    @Override
    public IPage<GfdRoleRefArea> getRoleRefAreaPage(Page page, GfdRoleRefArea roleRefArea) {
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        roleRefArea.setTenantId(tenantId);
        IPage<GfdRoleRefArea> roleRefAreaPage = baseMapper.getRoleRefAreaPage(page, roleRefArea);
        return roleRefAreaPage;
    }

    @Override
    public List<LinkappArea> getAreaListByRole(LinkappUser user) {
        List<Long> roleIds = user.getRoles().stream().map(LinkappRole::getId).collect(Collectors.toList());
        List<LinkappArea> areasByRoles = baseMapper.getAreasByRoles(roleIds);
        if(ObjectUtils.isEmpty(areasByRoles)){
            return Collections.emptyList();
        }
        return areasByRoles;
    }
}
